import 'dart:convert';
import 'dart:io';
import './PPSaltManager.dart';
import './PPUserInfoManager.dart';

enum PPRequestScheme {
    HTTP,
    HTTPS
}

enum PPRequestMothed {
    Post,
    Get
}

enum PPContentType {
    urlencoded,
    json
}

class PPRequest {

    static String requestHost =  "gpagw.sncfc.com.cn";

    static request(String url, Map param, Function succeedCallback, Function failCallback, {bool isEncryption = true, PPRequestMothed methodType = PPRequestMothed.Post, PPContentType contentType = PPContentType.urlencoded, PPRequestScheme schemeType = PPRequestScheme.HTTPS }) async {
        
        if(url == null || url.length == 0) {
            print('request url can not be empty');
            return;
        }
        var uri;
        Map<String, String> requestParam = PPRequest._getRequestParameter(param, isEncryption);
        if(schemeType == PPRequestScheme.HTTPS) {
            uri = Uri.https(requestHost, url, requestParam);
        } else {
            uri = Uri.http(requestHost, url, requestParam);
        }
        
        HttpClient httpClient = new HttpClient();
        print("[Request] url path ==== https://" + PPRequest.requestHost + url + "  ******* requestParam ====" + requestParam.toString());

        try {
            HttpClientRequest request;
            if(methodType == PPRequestMothed.Post) {
                request = await httpClient.postUrl(uri);
            } else {
                request = await httpClient.getUrl(uri);
            }
            
            ContentType headerContentType = PPRequest._getHeaderContentType(contentType);
            if(headerContentType != null) {
                request.headers.contentType = headerContentType;
            }

            HttpClientResponse response = await request.close();
            if (response.statusCode == 200) {
                response.transform(utf8.decoder).join().then((String result){
                    print("[Request Success] url path https://" + PPRequest.requestHost + url + "  ******* result ====" + result );
                    PPRequest.decodeResponse(result, succeedCallback);
                }) ;
            } else {
                String errMsg = response.reasonPhrase!= null && response.reasonPhrase.isNotEmpty ? response.reasonPhrase : "网络异常";
                print("[Request Fail] url path https://" + PPRequest.requestHost + url + "   ******* errMsg ====" + errMsg );
                failCallback({"code": '-1', "errMsg": errMsg});
            }
        } catch (exception) {
            String errMsg = exception.message != null && exception.message.isNotEmpty ? exception.message : "系统异常";
            print("[Request Fail] url https://" + PPRequest.requestHost + url + "   ******* errMsg ====" + errMsg);
            failCallback({"code": "-1", "errMsg": errMsg});
        }
    }

    static ContentType _getHeaderContentType(PPContentType contentType) {
        String headContentType = '';
        switch(contentType) {
            case PPContentType.urlencoded: {
                headContentType = "x-www-form-urlencoded";
                break;
            }
            case PPContentType.json: {
                headContentType = "json";
                break;
            }
            default: 
        }
        ContentType headerContentType = headContentType.isNotEmpty ? ContentType("application", headContentType, charset: "utf-8") : null;
        return headerContentType;
    }


    static Map<String, String> __getCommonParameter(bool isEncryption) {
        Map<String, String> commonParam = {};
        commonParam["terminalType"] = "03";
        commonParam["clientVersion"] = "1.0.0";
        commonParam["channelType"] = "03";
        commonParam["whoAmIType"] = "03";
        if (isEncryption && PPUserInfoManager().getRegId().isNotEmpty) {
            commonParam["regId"] = PPUserInfoManager().getRegId();
        }
        if (isEncryption && PPUserInfoManager().getClientSessionKey().isNotEmpty) {
            commonParam["clientSessionKey"] = PPUserInfoManager().getClientSessionKey();
        }

        return commonParam;
    }

    static Map<String, String> _getRequestParameter(Map bizData, bool isEncryption) {
        Map dataParam = Map.from(PPRequest.__getCommonParameter(isEncryption)); // 获取公用参数
        dataParam["bizData"] = bizData != null ? bizData : {}; // 添加业务参数
        String dataParamStr = json.encode(dataParam).toString();
        //是否需要加密的处理
        if(isEncryption) {
            dataParamStr = PPSaltManager().getPBEWithMd5AndDesEncrypt(dataParamStr);
        }
        final Map<String, String> requestParameter = {
            "deviceNo": "0d89a1be1e3c772968b4c6c9a870316d",
            "data": dataParamStr
        };
        return requestParameter;
    }

     static decodeResponse(String result, succeedCallback) {
        final dynamic resultJSON = json.decode(result);
        String type = resultJSON["type"];
        dynamic data = resultJSON["data"];
        if(type != "0") {
            data = PPSaltManager().getPBEWithMd5AndDesDecrypt(data);
            data = json.decode(data);
        }
        final dynamic bizData = data["bizData"];
        if(data["code"] == "0000") {
            succeedCallback(true, bizData, data);
        } else {
            succeedCallback(false, bizData, data);
        }
    }

}